<?php

/**
 * 文章类
 * 
 * @author ShuangYa
 * @package Blog
 * @category Library
 * @link http://www.sylingd.com/
 * @copyright Copyright (c) 2015 ShuangYa
 * @license http://lab.sylingd.com/go.php?name=blog&type=license
 */

namespace blog\libs;
use \Sy;
use \IXR_Client;
use \sy\lib\YHtml;
use \sy\lib\YMysql;
use \sy\base\SYException;
use \blog\libs\BMeta;
use \blog\libs\option;

class ArticleList_Action extends \blog\libs\List_Action {
	public $num;
	public $nowPage;
	public $find;
	/**
	 * 构造函数
	 * @access public
	 * @param array $list
	 */
	public function __construct($list, $num, $find) {
		$this->num = $num;
		$this->find = $find;
		$this->list = $list;
		reset($this->list);
	}
	/**
	 * 移到下一个
	 * @access public
	 * @return array
	 */
	public function next() {
		$r = each($this->list);
		if ($r === FALSE) {
			return FALSE;
		} else {
			return new Article_Action($r['value']);
		}
	}
	/**
	 * 获得页码总数
	 * @access public
	 * @return int
	 */
	public function getMaxPage() {
		$pagesize = intval(option::get('pagesize'));
		$max = intval(ceil($this->num / $pagesize));
		if ($max === 0) {
			$max = 1;
		}
		return $max;
	}
	/**
	 * 设置页码
	 * @access public
	 */
	public function setPage($page) {
		$this->nowPage = intval($page);
	}
	/**
	 * 输出页码导航
	 * @access public
	 * @param string $box
	 * @param string $current
	 */
	public function pageNav($box = 'li', $itemClass = 'item', $currentClass = 'active', $prev = '上一页', $next = '下一页', $aClass = '') {
		$maxPage = $this->getMaxPage();
		$nowPage = $this->nowPage;
		$current = ($nowPage>=3?$nowPage-2:1);
		$type = isset($this->find['find'])?$this->find['find']:'all';
		$val = isset($this->find[$type])?$this->find[$type]:'0';
		$aClassText = empty($aClass)?'':' class="' . $aClass . '"';
		$itemClassText = empty($itemClass)?'':' class="' . $itemClass . '"';
		if (!empty($prev) && $nowPage !== 1) {
			echo '<', $box, $itemClassText, '><a href="', Sy::createUrl(['article/list', 'type' => $type, 'val' => $val, 'page' => $nowPage - 1]);
			echo '"', $aClassText, '>', $prev, '</a></', $box, '>';
		}
		for ($i = 1;($i <= 5 && $current <= $maxPage);) {
			echo '<', $box;
			if ($current === $nowPage) {
				if (!empty($itemClass)) {
					echo ' class="', $currentClass, ' ', $itemClass, '"';
				} else {
					echo ' class="', $currentClass, '"';
				}
			}
			echo '><a';
			if ($current !== $nowPage) {
				echo ' href="', Sy::createUrl(['article/list', 'type' => $type, 'val' => $val, 'page' => $current]), '"';
			}
			echo $aClassText, '>', $current, '</a></', $box, '>';
			$i++;
			$current++;
		}
		if (!empty($next) && $nowPage !== $maxPage) {
			echo '<', $box, $itemClassText, '><a href="', Sy::createUrl(['article/list', 'type' => $type, 'val' => $val, 'page' => $nowPage + 1]);
			echo '"', $aClassText, '>', $next, '</a></', $box, '>';
		}
	}
}
//子类
class Article_Action extends \blog\libs\ListSub_Action {
	public function getDate($t) {
		return date($t, $this->sub['modify']);
	}
	public function date($t) {
		echo $this->getDate($t);
	}
	public function excerpt($num, $ext, $removeHtmlTag = TRUE) {
		if (!isset($this->sub['body'])) {
			return;
		}
		if ($removeHtmlTag) {
			$b = strip_tags($this->sub['body']);
		} else {
			$b = $this->sub['body'];
		}
		if (mb_strlen($b) > $num) {
			echo mb_substr($b, 0, $num), '&nbsp;', $ext;
		} else {
			echo $b;
		}
	}
	public function url($show = TRUE) {
		if ($show) {
			echo Sy::createUrl(['article/view', 'id' => $this->sub['id']]);
		} else {
			return Sy::createUrl(['article/view', 'id' => $this->sub['id']]);
		}
	}
	public function body($option = NULL) {
		$body = $this->sub['body'];
		if (!is_array($option) && $option !== NULL) {
			echo $body;
		} else {
			if (isset($option['imgClass'])) {
				$body = str_replace('<img ', '<img class="' . $option['imgClass'] . '" ', $body);
			}
			if (isset($option['lazyload']) && $option['lazyload']) {
				$body = preg_replace('/<img(.*?)src="(.*?)"/', '<img$1data-' .$option['lazyloadMeta'] . '="$2" src="' . $option['lazyloadImage'] . '"', $body);
			}
			if (isset($option['addNofollow']) && $option['addNofollow']) {
				$body = preg_replace_callback('/<a(.*?)href="(.*?)"/', function($matches) {
					$domain = $_SERVER['HTTP_HOST'];
					$url = $matches[2];
					if (substr($url, 0, 1) === '#' || strpos($url, $domain) !== FALSE || (substr($url, 0, 7) !== 'http://' && substr($url, 0, 8) !== 'https://')) {
						return $matches[0];
					}
					return $matches[0] . ' rel="nofollow"';
				}, $body);
			}
			echo $body;
		}
	}
}

class BArticle {
	/**
	 * 获取一篇文章
	 * @access public
	 * @param int $id
	 * @return array
	 */
	public static function get($id) {
		return new Article_Action(YMysql::_i()->getOne("SELECT * FROM `#@__article` WHERE id = ?", [$id]));
	}
	/**
	 * 修改一篇文章
	 * @access public
	 * @param int $id
	 * @param string $title 标题
	 * @param string $tags
	 * @param int $time
	 * @param string $body
	 */
	public static function set($id, $title, $tags, $time, $body = NULL) {
		$db = YMysql::_i();
		//处理Tag
		$new_tag = explode(',', $tags);
		$article = static::get($id);
		$old_tag = explode(',', $article->tags);
		//取差
		$add = array_diff($new_tag, $old_tag);
		$remove = array_diff($old_tag, $new_tag);
		foreach ($add as $t) {
			if (empty($t)) {
				continue;
			}
			//检查此Tag是否存在
			$tag_me = BMeta::getByName($t);
			if (!empty($tag_me['id'])) {
				$mid = $tag_me['id'];
			} else {
				$mid = BMeta::add($t);
			}
			$db->query('modify', "UPDATE `#@__meta` SET num = num+1 WHERE id = ?", [$mid]);
			$sql = "INSERT INTO `#@__relation`(`aid`,`mid`) VALUES ('$id','$mid')";
			$db->query('modify', $sql);
		}
		foreach ($remove as $t) {
			if (empty($t)) {
				continue;
			}
			$tag_me = BMeta::getByName($t);
			$mid = $tag_me['id'];
			$db->query('modify', "UPDATE `#@__meta` SET num = num-1 WHERE id = ?", [$mid]);
			$sql = "DELETE FROM `#@__relation` WHERE aid = ? AND mid = ?";
			$db->query('modify', $sql, [$id, $mid]);
		}
		//更新文章内容
		$title = addslashes($title);
		$tags = addslashes($tags);
		$sql = "UPDATE `#@__article` SET title = '$title', tags = '$tags', modify = '$time'";
		if ($body !== NULL) {
			$sql .= ", body = '" . addslashes($body) . "'";
		}
		$sql .= ' WHERE id = ?';
		$db->query('modify', $sql, [$id]);
		static::mkStatic($id);
	}
	/**
	 * 增加一篇文章
	 * @access public
	 * @param string $title 标题
	 * @param string $tags
	 * @param int $time
	 * @param string $body
	 * @return int
	 */
	public static function add($title, $tags, $time, $body) {
		$db = YMysql::_i();
		//插入文章
		$title = addslashes($title);
		$itags = addslashes($tags);
		$body = addslashes($body);
		$sql = "INSERT INTO `#@__article`(`title`,`tags`,`publish`,`modify`,`body`) VALUES ('$title','$tags','$time','$time','$body')";
		$db->query('add', $sql);
		$id = $db->getLastId();
		//处理Tag
		$tag = explode(',', $tags);
		foreach ($tag as $t) {
			if (empty($t)) {
				continue;
			}
			//检查此Tag是否存在
			$tag_me = BMeta::getByName($t);
			if (!empty($tag_me['id'])) {
				$mid = $tag_me['id'];
			} else {
				$mid = BMeta::add($t);
			}
			$db->query('add', "UPDATE `#@__meta` SET num = num+1 WHERE id = ?", [$mid]);
			$sql = "INSERT INTO `#@__relation`(`aid`,`mid`) VALUES ('$id','$mid')";
			$db->query('add', $sql);
		}
		static::sendPing($id);
		static::mkStatic($id);
		return $id;
	}
	/**
	 * 删除一篇文章
	 * @access public
	 * @param int $id
	 */
	public static function del($id) {
		$article = static::get($id);
		$title = $article->title;
		if (empty($title)) {
			return;
		}
		$tags = explode(',', $article->tags);
		foreach ($tags as $t) {
			YMysql::_i()->query('del', "UPDATE `#@__meta` SET num = num-1 WHERE title = ?", [$t]);
		}
		YMysql::_i()->query('del', 'DELETE FROM `#@__relation` WHERE aid = ?', [$id]);
		YMysql::_i()->query('del', 'DELETE FROM `#@__article` WHERE id = ?', [$id]);
	}
	/**
	 * 获取列表
	 * @access public
	 * @param array $param
	 * @param mixed $param[body] 是否返回文章内容
	 * @param mixed $param[find] 筛选方式
	 * @param string $param[id/tag] 筛选条件
	 * @param string $param[limit] 数量，SQL形式(0,30)
	 * @return Object(ArticleList_Action)
	 */
	public static function getList($param = []) {
		extract($param);
		if ($body) {
			if (isset($find)) {
				$row = 'a.*';
			} else {
				$row = '*';
			}
		} else {
			if (isset($find)) {
				$row = 'a.id,a.title,a.publish,a.modify,a.tags';
			} else {
				$row = 'id,title,publish,modify,tags';
			}
		}
		if ($find === 'id') {
			$sql = 'SELECT b.mid,' . $row . ' FROM `#@__article` a,`#@__relation` b WHERE a.id = b.aid AND b.mid = ? ORDER BY a.publish DESC ';
			$data = [$id];
		} elseif ($find === 'tag') {
			$sql = 'SELECT b.mid,' . $row . ' FROM `#@__article` a,`#@__relation` b,`#@__meta` c WHERE a.id = b.aid AND b.mid = c.id AND c.title = ? ORDER BY a.publish DESC ';
			$data = [$tag];
		} else {
			$sql = 'SELECT ' . $row . ' FROM `#@__article` ORDER BY publish DESC ';
			$data = [];
		}
		if (isset($limit)) {
			$sql .= 'LIMIT ' . $limit;
		}
		YMysql::_i()->query('list', $sql, $data);
		$r = YMysql::_i()->getAll('list');
		$num = static::getNum($param);
		return new ArticleList_Action($r, $num, $param);
	}
	/**
	 * 获取满足条件的文章数量
	 * @access public
	 * @param array $param
	 * @param mixed $param[find] 筛选方式
	 * @param string $param[id/tag] 筛选条件
	 * @return int
	 */
	public static function getNum($param = []) {
		if ($param['find'] === 'id') {
			$sql = 'SELECT count(*) as num FROM `#@__article` a,`#@__relation` b WHERE a.id = b.aid AND b.mid = ?';
			$data = [$param['id']];
		} elseif ($param['find'] === 'tag') {
			$sql = 'SELECT count(*) as num FROM `#@__article` a,`#@__relation` b,`#@__meta` c WHERE a.id = b.aid AND b.mid = c.id AND c.title = ?';
			$data = [$param['tag']];
		} else {
			$sql = 'SELECT count(*) as num FROM `#@__article`';
			$data = [];
		}
		$r = YMysql::_i()->getOne($sql, $data);
		return $r['num'];
	}
	/**
	 * 发送Ping通知和百度主动推送
	 * @access public
	 * @param int $id 文章ID
	 */
	public static function sendPing($id) {
		if (!class_exists('IXR_Client', FALSE)) {
			require(Sy::$appDir . 'third_party/IXR_Library.php');
		}
		$servers = explode("\n", option::get('seoPing'));
		foreach ($servers as $server) {
			$client = new IXR_Client($server);
			$client->timeout = 3; //较短的超时时间
			$client->useragent .= ' -- SYBlog/' . \blog\BVER;
			$client->query('weblogUpdates.extendedPing', option::get('sitename'), Sy::createUrl(), Sy::createUrl(['article/view'. 'id' => $id]), Sy::createUrl('feed/rss', 'xml'));
		}
		//百度主动推送
		$baiduSubmit = unserialize(option::get('seoBaiduSubmit'));
		if ($baiduSubmit['enable']) {
			\blog\curl_get('http://data.zz.baidu.com/urls?' . http_build_query(['site' => $baiduSubmit['site'], 'token' => $baiduSubmit['token']]), ['header' => ['Content-Type: text/plain'], 'post' => Sy::createUrl(['article/view'. 'id' => $id])]);
		}
	}
	/**
	 * 生成静态
	 * @access public
	 */
	public static function mkStatic($id) {
		if (option::get('static') == 1) {
			\blog\libs\MkHtml::mkArticle($id);
			\blog\libs\MkHtml::mkFeed('rss');
			\blog\libs\MkHtml::mkFeed('rdf');
			\blog\libs\MkHtml::mkFeed('atom');
		}
	}
}